home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / x / volume5 / xldimage / patch2 < prev    next >
Encoding:
Internet Message Format  |  1989-11-21  |  30.9 KB

  1. Path: uunet!island!world.std.com
  2. From: madd@world.std.com (jim frost)
  3. Newsgroups: comp.sources.x
  4. Subject: v05i030: xloadimage, Patch2
  5. Message-ID: <1206@island.uu.net>
  6. Date: 22 Nov 89 01:07:37 GMT
  7. Sender: argv@island.uu.net
  8. Lines: 1032
  9. Approved: island!argv@sun.com
  10.  
  11. Submitted-by: uunet!world.std.com!madd (jim frost)
  12. Posting-number: Volume 5, Issue 30
  13. Archive-name: xldimage/patch2
  14. Patch-To: xldimage: Volume 5, Issue 27,28
  15.  
  16.  
  17. The following shar contains new files and patches for xloadimage to
  18. bring it to patchlevel 02.  This corrects a bug in zooming bitmaps,
  19. some documentation errors, adds a new image format (XPM), and adds a
  20. new (but still simple) dithering algorithm.
  21.  
  22. Anyone who would like to implement a better dithering algorithm is
  23. encouraged to do so.
  24.  
  25. jim frost
  26. software tool & die
  27. madd@std.com
  28.  
  29. -- cut here --
  30. #! /bin/sh
  31. # This is a shell archive.  Remove anything before this line, then unpack
  32. # it by saving it into a file and typing "sh file".  To overwrite existing
  33. # files, type "sh file -c".  You can also feed this as standard input via
  34. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  35. # will see the following message at the end:
  36. #        "End of shell archive."
  37. # Contents:  patch.02 halftone.c xpixmap.c
  38. # Wrapped by madd@world on Mon Nov 20 17:07:36 1989
  39. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  40. if test -f patch.02 -a "${1}" != "-c" ; then 
  41.   echo shar: Will not over-write existing file \"patch.02\"
  42. else
  43. echo shar: Extracting \"patch.02\" \(18546 characters\)
  44. sed "s/^X//" >patch.02 <<'END_OF_patch.02'
  45. X*** Imakefile.orig    Mon Nov 20 16:10:40 1989
  46. X--- Imakefile    Mon Nov 20 16:17:15 1989
  47. X***************
  48. X*** 1,13 ****
  49. X!         DEFINES = -DSYSPATHFILE=\"/usr/lib/X11/xloadimage/xloadimagerc\"
  50. X          DEPLIBS = $(DEPLIBS)
  51. X  LOCAL_LIBRARIES = $(XLIB)
  52. X             SRCS = bright.c clip.c compress.c dither.c faces.c fill.c \
  53. X!           imagetypes.c merge.c misc.c new.c options.c path.c \
  54. X!           pbm.c reduce.c root.c send.c sunraster.c value.c \
  55. X!           window.c xbitmap.c xloadimage.c zio.c zoom.c
  56. X             OBJS = bright.o clip.o compress.o dither.o faces.o fill.o \
  57. X!           imagetypes.o merge.o misc.o new.o options.o path.o \
  58. X!           pbm.o reduce.o root.o send.o sunraster.o value.o \
  59. X!           window.o xbitmap.o xloadimage.o zio.o zoom.o
  60. X  
  61. X  ComplexProgramTarget(xloadimage)
  62. X--- 1,16 ----
  63. X!     SYSPATHFILE = $(USRLIBDIR)/xloadimagerc
  64. X!         DEFINES = -DSYSPATHFILE=\"$(SYSPATHFILE)\"
  65. X          DEPLIBS = $(DEPLIBS)
  66. X  LOCAL_LIBRARIES = $(XLIB)
  67. X             SRCS = bright.c clip.c compress.c dither.c faces.c fill.c \
  68. X!           halftone.c imagetypes.c merge.c misc.c new.c \
  69. X!           options.c path.c pbm.c reduce.c root.c send.c \
  70. X!           sunraster.c value.c window.c xbitmap.c xloadimage.c \
  71. X!           xpixmap.c zio.c zoom.c
  72. X             OBJS = bright.o clip.o compress.o dither.o faces.o fill.o \
  73. X!           halftone.o imagetypes.o merge.o misc.o new.o \
  74. X!           options.o path.o pbm.o reduce.o root.o send.o \
  75. X!           sunraster.o value.o window.o xbitmap.o xloadimage.o \
  76. X!           xpixmap.o zio.o zoom.o
  77. X  
  78. X  ComplexProgramTarget(xloadimage)
  79. X*** Makefile.gcc.orig    Mon Nov 20 16:10:41 1989
  80. X--- Makefile.gcc    Mon Nov 20 16:18:54 1989
  81. X***************
  82. X*** 8,16 ****
  83. X  CFLAGS= -O -fstrength-reduce -finline-functions -DSYSPATHFILE=\"/usr/lib/xloadimagerc\"
  84. X  
  85. X  LIBS= -lX11
  86. X! OBJS= bright.o clip.o compress.o dither.o faces.o fill.o imagetypes.o \
  87. X!       merge.o misc.o new.o options.o path.o pbm.o reduce.o root.o send.o \
  88. X!       sunraster.o value.o window.o xbitmap.o xloadimage.o zio.o zoom.o
  89. X  
  90. X  xloadimage: $(OBJS)
  91. X      $(CC) $(CFLAGS) -o xloadimage $(OBJS) $(LIBS)
  92. X--- 8,17 ----
  93. X  CFLAGS= -O -fstrength-reduce -finline-functions -DSYSPATHFILE=\"/usr/lib/xloadimagerc\"
  94. X  
  95. X  LIBS= -lX11
  96. X! OBJS= bright.o clip.o compress.o dither.o faces.o fill.o \
  97. X!       halftone.o imagetypes.o merge.o misc.o new.o options.o path.o \
  98. X!       pbm.o reduce.o root.o send.o sunraster.o value.o window.o \
  99. X!       xbitmap.o xloadimage.o xpixmap.o zio.o zoom.o
  100. X  
  101. X  xloadimage: $(OBJS)
  102. X      $(CC) $(CFLAGS) -o xloadimage $(OBJS) $(LIBS)
  103. X*** Makefile.std.orig    Mon Nov 20 16:41:09 1989
  104. X--- Makefile.std    Mon Nov 20 16:38:39 1989
  105. X***************
  106. X*** 8,16 ****
  107. X  CFLAGS= -O -DSYSPATHFILE=\"/usr/lib/xloadimagerc\"
  108. X  
  109. X  LIBS= -lX11
  110. X! OBJS= bright.o clip.o compress.o dither.o faces.o fill.o imagetypes.o \
  111. X!       merge.o misc.o new.o options.o path.o pbm.o reduce.o root.o send.o \
  112. X!       sunraster.o value.o window.o xbitmap.o xloadimage.o zio.o zoom.o
  113. X  
  114. X  xloadimage: $(OBJS)
  115. X      $(CC) $(CFLAGS) -o xloadimage $(OBJS) $(LIBS)
  116. X--- 8,17 ----
  117. X  CFLAGS= -O -DSYSPATHFILE=\"/usr/lib/xloadimagerc\"
  118. X  
  119. X  LIBS= -lX11
  120. X! OBJS= bright.o clip.o compress.o dither.o faces.o fill.o \
  121. X!       halftone.o imagetypes.o merge.o misc.o new.o options.o path.o \
  122. X!       pbm.o reduce.o root.o send.o sunraster.o value.o window.o \
  123. X!       xbitmap.o xloadimage.o xpixmap.o zio.o zoom.o
  124. X  
  125. X  xloadimage: $(OBJS)
  126. X      $(CC) $(CFLAGS) -o xloadimage $(OBJS) $(LIBS)
  127. X*** dither.c.orig    Mon Nov 20 16:10:44 1989
  128. X--- dither.c    Mon Nov 20 16:15:07 1989
  129. X***************
  130. X*** 1,13 ****
  131. X  /* dither.c:
  132. X   *
  133. X!  * routine for dithering a color image to monochrome based on color
  134. X!  * intensity.  this is loosely based on an algorithm which barry shein
  135. X!  * (bzs@std.com) used in his "xf" program.
  136. X   *
  137. X   * jim frost 07.10.89
  138. X   *
  139. X!  * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
  140. X!  * copyright information.
  141. X   */
  142. X  
  143. X  #include "copyright.h"
  144. X--- 1,14 ----
  145. X  /* dither.c:
  146. X   *
  147. X!  * this is a modified version of the dithering algorithm in halftone.c
  148. X!  * which doesn't enlarge the image.  modifications made by
  149. X!  * Steve Losen (scl@virginia.edu).
  150. X   *
  151. X   * jim frost 07.10.89
  152. X+  * Steve Losen 11.17.89
  153. X   *
  154. X!  * Copyright 1989 Jim Frost and Steve Losen.  See included file
  155. X!  * "copyright.h" for complete copyright information.
  156. X   */
  157. X  
  158. X  #include "copyright.h"
  159. X***************
  160. X*** 21,41 ****
  161. X  
  162. X  static byte DitherBits[GRAYS][4] = {
  163. X    0xf, 0xf, 0xf, 0xf,
  164. X!   0xe, 0xf, 0xf, 0xf,
  165. X!   0xe, 0xf, 0xb, 0xf,
  166. X!   0xa, 0xf, 0xb, 0xf,
  167. X!   0xa, 0xf, 0xa, 0xf,
  168. X!   0xa, 0xd, 0xa, 0xf,
  169. X!   0xa, 0xd, 0xa, 0x7,
  170. X!   0xa, 0x5, 0xa, 0x7,
  171. X!   0xa, 0x5, 0xa, 0x5,
  172. X!   0x8, 0x5, 0xa, 0x5,
  173. X!   0x8, 0x5, 0x2, 0x5,
  174. X!   0x0, 0x5, 0x2, 0x5,
  175. X!   0x0, 0x5, 0x0, 0x5,
  176. X!   0x0, 0x4, 0x0, 0x5,
  177. X!   0x0, 0x4, 0x0, 0x1,
  178. X!   0x0, 0x0, 0x0, 0x1,
  179. X    0x0, 0x0, 0x0, 0x0
  180. X  };
  181. X  
  182. X--- 22,42 ----
  183. X  
  184. X  static byte DitherBits[GRAYS][4] = {
  185. X    0xf, 0xf, 0xf, 0xf,
  186. X!   0xf, 0xf, 0xf, 0x7,
  187. X!   0xf, 0xf, 0xf, 0x3,
  188. X!   0xf, 0xf, 0x7, 0x3,
  189. X!   0xf, 0xf, 0x3, 0x3,
  190. X!   0xf, 0xf, 0x3, 0x1,
  191. X!   0xf, 0x7, 0x3, 0x1,
  192. X!   0xf, 0x7, 0x1, 0x1,
  193. X!   0x7, 0x7, 0x3, 0x0,
  194. X!   0x7, 0x7, 0x1, 0x0,
  195. X!   0x7, 0x3, 0x1, 0x0,
  196. X!   0x7, 0x3, 0x0, 0x0,
  197. X!   0x3, 0x3, 0x0, 0x0,
  198. X!   0x3, 0x1, 0x0, 0x0,
  199. X!   0x3, 0x0, 0x0, 0x0,
  200. X!   0x1, 0x0, 0x0, 0x0,
  201. X    0x0, 0x0, 0x0, 0x0
  202. X  };
  203. X  
  204. X***************
  205. X*** 65,71 ****
  206. X      printf("  Dithering image...");
  207. X      fflush(stdout);
  208. X    }
  209. X!   image= newBitImage(cimage->width * 4, cimage->height * 4);
  210. X    if (cimage->title) {
  211. X      image->title= (char *)malloc(strlen(cimage->title) + 12);
  212. X      sprintf(image->title, "%s (dithered)", cimage->title);
  213. X--- 66,72 ----
  214. X      printf("  Dithering image...");
  215. X      fflush(stdout);
  216. X    }
  217. X!   image= newBitImage(cimage->width, cimage->height);
  218. X    if (cimage->title) {
  219. X      image->title= (char *)malloc(strlen(cimage->title) + 12);
  220. X      sprintf(image->title, "%s (dithered)", cimage->title);
  221. X***************
  222. X*** 99,105 ****
  223. X    dp= image->data;
  224. X    for (y= 0; y < cimage->height; y++) {
  225. X      for (x= 0; x < cimage->width; x++) {
  226. X-       dp2= dp + (x >> 1);
  227. X        color= memToVal(sp, spl);
  228. X        if (index)
  229. X      dindex= *(index + color);
  230. X--- 100,105 ----
  231. X***************
  232. X*** 107,130 ****
  233. X      dindex= ((unsigned long)(*(cimage->rgb.red + color)) +
  234. X           *(cimage->rgb.green + color) +
  235. X           *(cimage->rgb.blue + color)) / GRAYSTEP;
  236. X! 
  237. X!       /* loop for the four Y bits in the dither pattern, putting all
  238. X!        * four X bits in at once.  if you think this would be hard to
  239. X!        * change to be an NxN dithering array, you're right, since we're
  240. X!        * banking on the fact that we need only shift the mask based on
  241. X!        * whether x is odd or not.  an 8x8 array wouldn't even need that,
  242. X!        * but blowing an image up by 64x is probably not a feature.
  243. X!        */
  244. X! 
  245. X!       if (x & 1)
  246. X!     for (a= 0; a < 4; a++, dp2 += dll)
  247. X!       *dp2 |= DitherBits[dindex][a];
  248. X!       else
  249. X!     for (a= 0; a < 4; a++, dp2 += dll)
  250. X!       *dp2 |= (DitherBits[dindex][a] << 4);
  251. X        sp += spl;
  252. X      }
  253. X!     dp += (dll << 2); /* (dll * 4) but I like shifts */
  254. X    }
  255. X    if (verbose)
  256. X      printf("done\n");
  257. X--- 107,117 ----
  258. X      dindex= ((unsigned long)(*(cimage->rgb.red + color)) +
  259. X           *(cimage->rgb.green + color) +
  260. X           *(cimage->rgb.blue + color)) / GRAYSTEP;
  261. X!       if (DitherBits[dindex][y & 3] & (1 << (x & 3)))
  262. X!      dp[x / 8] |= 1 << (7 - (x & 7));
  263. X        sp += spl;
  264. X      }
  265. X!     dp += dll;
  266. X    }
  267. X    if (verbose)
  268. X      printf("done\n");
  269. X*** image.h.orig    Mon Nov 20 16:10:45 1989
  270. X--- image.h    Mon Nov 20 16:15:08 1989
  271. X***************
  272. X*** 60,65 ****
  273. X--- 60,67 ----
  274. X  
  275. X  void fold(); /* fold.c */
  276. X  
  277. X+ Image *halftone(); /* halftone.c */
  278. X+ 
  279. X  Image *loadImage(); /* imagetypes.c */
  280. X  void   identifyImage();
  281. X  void   goodImage();
  282. X***************
  283. X*** 82,86 ****
  284. X--- 84,90 ----
  285. X  
  286. X  unsigned long memToVal(); /* value.c */
  287. X  void          valToMem();
  288. X+ unsigned long memToValLSB();
  289. X+ void          valToMemLSB();
  290. X  
  291. X  Image *zoom(); /* zoom.c */
  292. X*** imagetypes.h.orig    Mon Nov 20 16:10:46 1989
  293. X--- imagetypes.h    Mon Nov 20 16:19:13 1989
  294. X***************
  295. X*** 19,24 ****
  296. X--- 19,27 ----
  297. X  int xbitmapIdent();
  298. X  int xpixmapIdent();
  299. X  
  300. X+ /* some of these are order-dependent
  301. X+  */
  302. X+ 
  303. X  struct {
  304. X    int    (*identifier)(); /* print out image info if this kind of image */
  305. X    Image *(*loader)();     /* load image if this kind of image */
  306. X***************
  307. X*** 27,32 ****
  308. X--- 30,36 ----
  309. X    sunRasterIdent, sunRasterLoad, "Sun Rasterfile",
  310. X    pbmIdent,       pbmLoad,       "Portable Bit Map (PBM)",
  311. X    facesIdent,     facesLoad,     "Faces Project",
  312. X+   xpixmapIdent,   xpixmapLoad,   "X Pixmap",
  313. X    xbitmapIdent,   xbitmapLoad,   "X Bitmap",
  314. X    NULL,           NULL,          NULL
  315. X  };
  316. X*** misc.c.orig    Mon Nov 20 16:10:47 1989
  317. X--- misc.c    Mon Nov 20 16:15:09 1989
  318. X***************
  319. X*** 39,44 ****
  320. X--- 39,45 ----
  321. X    printf("  -clip X,Y,W,H         - use clipped portion of image\n");
  322. X    printf("  -dither               - dither color image to bitmap image\n");
  323. X    printf("  -foreground colorname - foreground color for bitmap images\n");
  324. X+   printf("  -halftone             - halftone a color image to bitmap image\n");
  325. X    printf("  -name name            - force next argument to be image name\n");
  326. X    printf("  -xzoom percentage     - zoom the X axis by a percentage\n");
  327. X    printf("  -yzoom percentage     - zoom the Y axis by a percentage\n");
  328. X***************
  329. X*** 111,117 ****
  330. X    }
  331. X  
  332. X    if (options->dither && (image->depth > 1)) { /* image is to be dithered */
  333. X!     tmpimage= dither(image, verbose);
  334. X      freeImage(image);
  335. X      image= tmpimage;
  336. X      options->clipx *= 4;      /* image was blown up by 4 */
  337. X--- 112,121 ----
  338. X    }
  339. X  
  340. X    if (options->dither && (image->depth > 1)) { /* image is to be dithered */
  341. X!     if (options->dither == 1)
  342. X!       tmpimage= dither(image, verbose);
  343. X!     else
  344. X!       tmpimage= halftone(image, verbose);
  345. X      freeImage(image);
  346. X      image= tmpimage;
  347. X      options->clipx *= 4;      /* image was blown up by 4 */
  348. X*** value.c.orig    Mon Nov 20 16:10:59 1989
  349. X--- value.c    Mon Nov 20 16:15:11 1989
  350. X***************
  351. X*** 36,38 ****
  352. X--- 36,64 ----
  353. X      val >>= 8;
  354. X    }
  355. X  }
  356. X+ 
  357. X+ unsigned long memToValLSB(p, len)
  358. X+      byte         *p;
  359. X+      unsigned int  len;
  360. X+ { int val, a;
  361. X+ 
  362. X+   val= 0;
  363. X+   for (a= len - 1; a >= 0; a--)
  364. X+     val= (val << 8) + *(p + a);
  365. X+   return(val);
  366. X+ }
  367. X+ 
  368. X+ /* this is provided for orthagonality
  369. X+  */
  370. X+ 
  371. X+ void valToMemLSB(val, p, len)
  372. X+      byte          *p;
  373. X+      unsigned long  val;
  374. X+      unsigned int   len;
  375. X+ { int a;
  376. X+ 
  377. X+   while (len--) {
  378. X+     *(p++)= val & 0xff;
  379. X+     val >>= 8;
  380. X+   }
  381. X+ }
  382. X*** xloadimage.c.orig    Mon Nov 20 16:11:01 1989
  383. X--- xloadimage.c    Mon Nov 20 16:15:12 1989
  384. X***************
  385. X*** 37,42 ****
  386. X--- 37,43 ----
  387. X    "colors",
  388. X    "dither",
  389. X    "foreground",
  390. X+   "halftone",
  391. X    "name",
  392. X    "xzoom",
  393. X    "yzoom",
  394. X***************
  395. X*** 66,76 ****
  396. X  #define COLORS     18
  397. X  #define DITHER     19
  398. X  #define FOREGROUND 20
  399. X! #define NAME       21
  400. X! #define XZOOM      22
  401. X! #define YZOOM      23
  402. X! #define ZOOM       24
  403. X  
  404. X  /* the real thing
  405. X   */
  406. X  
  407. X--- 67,86 ----
  408. X  #define COLORS     18
  409. X  #define DITHER     19
  410. X  #define FOREGROUND 20
  411. X! #define HALFTONE   21
  412. X! #define NAME       22
  413. X! #define XZOOM      23
  414. X! #define YZOOM      24
  415. X! #define ZOOM       25
  416. X  
  417. X+ /* if an image loader needs to have our display and screen, it will get
  418. X+  * them from here.  this is done to keep most of the image routines
  419. X+  * clean
  420. X+  */
  421. X+ 
  422. X+ Display *Disp= NULL;
  423. X+ int      Scrn= 0;
  424. X+ 
  425. X  /* the real thing
  426. X   */
  427. X  
  428. X***************
  429. X*** 246,251 ****
  430. X--- 256,265 ----
  431. X        images[imagecount].fg= argv[++a];
  432. X        break;
  433. X  
  434. X+     case HALFTONE:
  435. X+       images[imagecount].dither= 2;
  436. X+       break;
  437. X+ 
  438. X      case NAME:
  439. X        if (imagecount == MAXIMAGES)
  440. X      printf("%s: Too many images (ignoring)\n", argv[++a]);
  441. X***************
  442. X*** 287,297 ****
  443. X    /* start talking to the display
  444. X     */
  445. X  
  446. X!   if (! (disp= XOpenDisplay(dname))) {
  447. X      printf("%s: Cannot open display\n", XDisplayName(dname));
  448. X      exit(1);
  449. X    }
  450. X!   scrn= DefaultScreen(disp);
  451. X    XSetIOErrorHandler(ioErrorHandler);
  452. X  
  453. X    dispimage= NULL;
  454. X--- 301,311 ----
  455. X    /* start talking to the display
  456. X     */
  457. X  
  458. X!   if (! (Disp= disp= XOpenDisplay(dname))) {
  459. X      printf("%s: Cannot open display\n", XDisplayName(dname));
  460. X      exit(1);
  461. X    }
  462. X!   Scrn= scrn= DefaultScreen(disp);
  463. X    XSetIOErrorHandler(ioErrorHandler);
  464. X  
  465. X    dispimage= NULL;
  466. X***************
  467. X*** 325,332 ****
  468. X    for (a= 0; a < imagecount; a++) {
  469. X      if (! (newimage= loadImage(images[a].name, verbose)))
  470. X        continue;
  471. X!     if ((dispimage && BITMAPP(dispimage)) || (DefaultDepth(disp, scrn) == 1))
  472. X!       images[a].dither= 1;
  473. X      newimage= processImage(disp, scrn, newimage, &images[a], verbose);
  474. X      if (!images[a].clipw && !images[a].cliph) {
  475. X        images[a].clipw= newimage->width;
  476. X--- 339,347 ----
  477. X    for (a= 0; a < imagecount; a++) {
  478. X      if (! (newimage= loadImage(images[a].name, verbose)))
  479. X        continue;
  480. X!     if (!images[a].dither &&
  481. X!     ((dispimage && BITMAPP(dispimage)) || (DefaultDepth(disp, scrn) == 1)))
  482. X!       images[a].dither= 2;
  483. X      newimage= processImage(disp, scrn, newimage, &images[a], verbose);
  484. X      if (!images[a].clipw && !images[a].cliph) {
  485. X        images[a].clipw= newimage->width;
  486. X*** xloadimage.man.orig    Mon Nov 20 16:53:22 1989
  487. X--- xloadimage.man    Mon Nov 20 17:06:00 1989
  488. X***************
  489. X*** 13,19 ****
  490. X  If the destination display cannot support the number of colors in the
  491. X  image, the image will be dithered (monochrome destination) or have its
  492. X  colormap reduced (color destination) as appropriate.  This can also be
  493. X! done forcibly with the \fI-dither\fR and \fI-colors\fR options.
  494. X  .PP
  495. X  If more than one image is to be loaded, they will be merged into a
  496. X  single image.  The \fI-at\fR and \fI-center\fR options control where
  497. X--- 13,19 ----
  498. X  If the destination display cannot support the number of colors in the
  499. X  image, the image will be dithered (monochrome destination) or have its
  500. X  colormap reduced (color destination) as appropriate.  This can also be
  501. X! done forcibly with the \fI-halftone\fR and \fI-colors\fR options.
  502. X  .PP
  503. X  If more than one image is to be loaded, they will be merged into a
  504. X  single image.  The \fI-at\fR and \fI-center\fR options control where
  505. X***************
  506. X*** 128,136 ****
  507. X  interpreted as the remainder of the image. 
  508. X  .TP
  509. X  -dither
  510. X! Force halftone dithering of a color image when displaying on a color
  511. X! display.  This happens by default when viewing color images on a
  512. X! monochrome display.  This option is ignored on monochrome images. 
  513. X  .TP
  514. X  -foreground \fIcolor\fR
  515. X  Use \fIcolor\fR as the foreground color instead of black if you are
  516. X--- 128,136 ----
  517. X  interpreted as the remainder of the image. 
  518. X  .TP
  519. X  -dither
  520. X! Dither a color image to monochrome.  This algorithm is very trivial;
  521. X! the \fI-halftone\fR option may look better if you don't mind the
  522. X! blown-up image.
  523. X  .TP
  524. X  -foreground \fIcolor\fR
  525. X  Use \fIcolor\fR as the foreground color instead of black if you are
  526. X***************
  527. X*** 138,143 ****
  528. X--- 138,151 ----
  529. X  used to invert the foreground and background colors of a monochrome
  530. X  image. 
  531. X  .TP
  532. X+ -halftone
  533. X+ Force halftone dithering of a color image when displaying on a
  534. X+ monochrome display.  This happens by default when viewing color images
  535. X+ on a monochrome display.  This option is ignored on monochrome images.
  536. X+ This dithering algorithm blows an image up by sixteen times; if you
  537. X+ don't like this, the \fI-dither\fR option will not blow the image up
  538. X+ (but won't look as nice).
  539. X+ .TP
  540. X  -name \fIimage_name\fR
  541. X  Force the next argument to be treated as an image name.  This is
  542. X  useful if the name of the image is \fI-dither\fR, for instance. 
  543. X***************
  544. X*** 208,213 ****
  545. X--- 216,222 ----
  546. X    Sun color RGB rasterfiles
  547. X    X10 bitmap files
  548. X    X11 bitmap files
  549. X+   X pixmap files
  550. X  .fi
  551. X  .PP
  552. X  Both normal and compact PBM images are supported.  Both standard and
  553. X***************
  554. X*** 219,224 ****
  555. X--- 228,235 ----
  556. X  madd@std.com
  557. X  .fi
  558. X  .SH BUGS
  559. X+ Zooming dithered images is UGLY.
  560. X+ .PP
  561. X  Loading images onto the root with PseudoColor or GrayScale displays
  562. X  can cause colormap problems (and may interfere with window manager
  563. X  operation) if there are not enough colors in the default colormap to
  564. X*** zoom.c.orig    Mon Nov 20 16:11:03 1989
  565. X--- zoom.c    Mon Nov 20 16:15:13 1989
  566. X***************
  567. X*** 46,53 ****
  568. X    unsigned int  x, y, xsrc, ysrc;
  569. X    unsigned int  pixlen;
  570. X    unsigned int  srclinelen;
  571. X    byte         *srcline, *srcptr;
  572. X!   byte         *destptr;
  573. X    byte          srcmask, destmask, bit;
  574. X    Pixel         value;
  575. X  
  576. X--- 46,54 ----
  577. X    unsigned int  x, y, xsrc, ysrc;
  578. X    unsigned int  pixlen;
  579. X    unsigned int  srclinelen;
  580. X+   unsigned int  destlinelen;
  581. X    byte         *srcline, *srcptr;
  582. X!   byte         *destline, *destptr;
  583. X    byte          srcmask, destmask, bit;
  584. X    Pixel         value;
  585. X  
  586. X***************
  587. X*** 90,96 ****
  588. X        *(image->rgb.blue + x)= *(oimage->rgb.blue + x);
  589. X      }
  590. X      image->rgb.used= oimage->rgb.used;
  591. X!     destptr= image->data;
  592. X      srcline= oimage->data;
  593. X      srclinelen= (oimage->width / 8) + (oimage->width % 8 ? 1 : 0);
  594. X      for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) {
  595. X--- 91,98 ----
  596. X        *(image->rgb.blue + x)= *(oimage->rgb.blue + x);
  597. X      }
  598. X      image->rgb.used= oimage->rgb.used;
  599. X!     destline= image->data;
  600. X!     destlinelen= (xwidth / 8) + (xwidth % 8 ? 1 : 0);
  601. X      srcline= oimage->data;
  602. X      srclinelen= (oimage->width / 8) + (oimage->width % 8 ? 1 : 0);
  603. X      for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) {
  604. X***************
  605. X*** 99,104 ****
  606. X--- 101,107 ----
  607. X      srcline += srclinelen;
  608. X        }
  609. X        srcptr= srcline;
  610. X+       destptr= destline;
  611. X        srcmask= 0x80;
  612. X        destmask= 0x80;
  613. X        bit= srcmask & *srcptr;
  614. X***************
  615. X*** 120,125 ****
  616. X--- 123,129 ----
  617. X        destptr++;
  618. X      }
  619. X        }
  620. X+       destline += destlinelen;
  621. X      }
  622. X      break;
  623. X  
  624. X*** README.orig    Mon Nov 20 16:10:42 1989
  625. X--- README    Mon Nov 20 16:33:15 1989
  626. X***************
  627. X*** 97,99 ****
  628. X--- 97,104 ----
  629. X  windows by typing 'q' was submitted by Chris Tengi
  630. X  (tengi@idunno.princeton.edu) and was included.  The previously missing
  631. X  file 'patchlevel' was included.
  632. X+ 
  633. X+ Patch 02 contained modifications to the Makefiles, support for the X
  634. X+ Pixmap image type, a different dithering algorithm that didn't blow
  635. X+ the image up (with the old one moved to halftone.c), and a bug fix to
  636. X+ zoom.c to correct problems when zooming bitmaps.
  637. X*** patchlevel.orig    Mon Nov 20 16:41:17 1989
  638. X--- patchlevel    Mon Nov 20 16:47:04 1989
  639. X***************
  640. X*** 1 ****
  641. X! PATCHLEVEL 01
  642. X--- 1 ----
  643. X! PATCHLEVEL 02
  644. END_OF_patch.02
  645. if test 18546 -ne `wc -c <patch.02`; then
  646.     echo shar: \"patch.02\" unpacked with wrong size!
  647. fi
  648. # end of overwriting check
  649. fi
  650. if test -f halftone.c -a "${1}" != "-c" ; then 
  651.   echo shar: Will not over-write existing file \"halftone.c\"
  652. else
  653. echo shar: Extracting \"halftone.c\" \(3916 characters\)
  654. sed "s/^X//" >halftone.c <<'END_OF_halftone.c'
  655. X/* dither.c:
  656. X *
  657. X * routine for dithering a color image to monochrome based on color
  658. X * intensity.  this is loosely based on an algorithm which barry shein
  659. X * (bzs@std.com) used in his "xf" program.
  660. X *
  661. X * jim frost 07.10.89
  662. X *
  663. X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
  664. X * copyright information.
  665. X */
  666. X
  667. X#include "copyright.h"
  668. X#include "image.h"
  669. X
  670. X/* 4x4 arrays used for dithering, arranged by nybble
  671. X */
  672. X
  673. X#define GRAYS    17 /* ((4 * 4) + 1) patterns for a good dither */
  674. X#define GRAYSTEP ((unsigned long)(65536 * 3) / GRAYS)
  675. X
  676. Xstatic byte DitherBits[GRAYS][4] = {
  677. X  0xf, 0xf, 0xf, 0xf,
  678. X  0xe, 0xf, 0xf, 0xf,
  679. X  0xe, 0xf, 0xb, 0xf,
  680. X  0xa, 0xf, 0xb, 0xf,
  681. X  0xa, 0xf, 0xa, 0xf,
  682. X  0xa, 0xd, 0xa, 0xf,
  683. X  0xa, 0xd, 0xa, 0x7,
  684. X  0xa, 0x5, 0xa, 0x7,
  685. X  0xa, 0x5, 0xa, 0x5,
  686. X  0x8, 0x5, 0xa, 0x5,
  687. X  0x8, 0x5, 0x2, 0x5,
  688. X  0x0, 0x5, 0x2, 0x5,
  689. X  0x0, 0x5, 0x0, 0x5,
  690. X  0x0, 0x4, 0x0, 0x5,
  691. X  0x0, 0x4, 0x0, 0x1,
  692. X  0x0, 0x0, 0x0, 0x1,
  693. X  0x0, 0x0, 0x0, 0x0
  694. X};
  695. X
  696. X/* simple dithering algorithm, really optimized for the 4x4 array
  697. X */
  698. X
  699. XImage *halftone(cimage, verbose)
  700. X     Image        *cimage;
  701. X     unsigned int  verbose;
  702. X{ Image         *image;
  703. X  unsigned char *sp, *dp, *dp2; /* data pointers */
  704. X  unsigned int   dindex;        /* index into dither array */
  705. X  unsigned int   spl;           /* source pixel length in bytes */
  706. X  unsigned int   dll;           /* destination line length in bytes */
  707. X  Pixel          color;         /* pixel color */
  708. X  unsigned int  *index;         /* index into dither array for a given pixel */
  709. X  unsigned int   a, x, y;       /* random counters */
  710. X
  711. X  goodImage(cimage, "dither");
  712. X  if (! RGBP(cimage))
  713. X    return(NULL);
  714. X
  715. X  /* set up
  716. X   */
  717. X
  718. X  if (verbose) {
  719. X    printf("  Dithering image...");
  720. X    fflush(stdout);
  721. X  }
  722. X  image= newBitImage(cimage->width * 4, cimage->height * 4);
  723. X  if (cimage->title) {
  724. X    image->title= (char *)malloc(strlen(cimage->title) + 12);
  725. X    sprintf(image->title, "%s (dithered)", cimage->title);
  726. X  }
  727. X  spl= cimage->pixlen;
  728. X  dll= (image->width / 8) + (image->width % 8 ? 1 : 0);
  729. X
  730. X  /* if the number of possible pixels isn't very large, build an array
  731. X   * which we index by the pixel value to find the dither array index
  732. X   * by color brightness.  we do this in advance so we don't have to do
  733. X   * it for each pixel.  things will break if a pixel value is greater
  734. X   * than (1 << depth), which is bogus anyway.  this calculation is done
  735. X   * on a per-pixel basis if the colormap is too big.
  736. X   */
  737. X
  738. X  if (cimage->depth <= 16) {
  739. X    index= (unsigned int *)malloc(sizeof(unsigned int) * cimage->rgb.used);
  740. X    for (x= 0; x < cimage->rgb.used; x++)
  741. X      *(index + x)=
  742. X    ((unsigned long)(*(cimage->rgb.red + x)) +
  743. X     *(cimage->rgb.green + x) +
  744. X     *(cimage->rgb.blue + x)) / GRAYSTEP;
  745. X  }
  746. X  else
  747. X    index= NULL;
  748. X
  749. X  /* dither each pixel
  750. X   */
  751. X
  752. X  sp= cimage->data;
  753. X  dp= image->data;
  754. X  for (y= 0; y < cimage->height; y++) {
  755. X    for (x= 0; x < cimage->width; x++) {
  756. X      dp2= dp + (x >> 1);
  757. X      color= memToVal(sp, spl);
  758. X      if (index)
  759. X    dindex= *(index + color);
  760. X      else
  761. X    dindex= ((unsigned long)(*(cimage->rgb.red + color)) +
  762. X         *(cimage->rgb.green + color) +
  763. X         *(cimage->rgb.blue + color)) / GRAYSTEP;
  764. X
  765. X      /* loop for the four Y bits in the dither pattern, putting all
  766. X       * four X bits in at once.  if you think this would be hard to
  767. X       * change to be an NxN dithering array, you're right, since we're
  768. X       * banking on the fact that we need only shift the mask based on
  769. X       * whether x is odd or not.  an 8x8 array wouldn't even need that,
  770. X       * but blowing an image up by 64x is probably not a feature.
  771. X       */
  772. X
  773. X      if (x & 1)
  774. X    for (a= 0; a < 4; a++, dp2 += dll)
  775. X      *dp2 |= DitherBits[dindex][a];
  776. X      else
  777. X    for (a= 0; a < 4; a++, dp2 += dll)
  778. X      *dp2 |= (DitherBits[dindex][a] << 4);
  779. X      sp += spl;
  780. X    }
  781. X    dp += (dll << 2); /* (dll * 4) but I like shifts */
  782. X  }
  783. X  if (verbose)
  784. X    printf("done\n");
  785. X  return(image);
  786. X}
  787. END_OF_halftone.c
  788. if test 3916 -ne `wc -c <halftone.c`; then
  789.     echo shar: \"halftone.c\" unpacked with wrong size!
  790. fi
  791. # end of overwriting check
  792. fi
  793. if test -f xpixmap.c -a "${1}" != "-c" ; then 
  794.   echo shar: Will not over-write existing file \"xpixmap.c\"
  795. else
  796. echo shar: Extracting \"xpixmap.c\" \(5707 characters\)
  797. sed "s/^X//" >xpixmap.c <<'END_OF_xpixmap.c'
  798. X/* xpixmap.c:
  799. X *
  800. X * XPixMap format file read and identify routines.  these can handle any
  801. X * "format 1" XPixmap file with up to BUFSIZ - 1 chars per pixel.  it's
  802. X * not nearly as picky as it might be.
  803. X *
  804. X * unlike most image loading routines, this is X specific since it
  805. X * requires X color name parsing.  to handle this we have global X
  806. X * variables for display and screen.  it's ugly but it keeps the rest
  807. X * of the image routines clean.
  808. X *
  809. X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
  810. X * copyright information.
  811. X */
  812. X
  813. X#include "copyright.h"
  814. X#include "xloadimage.h"
  815. X
  816. Xchar *rindex();
  817. X
  818. Xextern Display *Disp; /* X display, null if in "identify" mode */
  819. Xextern int      Scrn; /* X screen number */
  820. X
  821. X#define XPM_FORMAT 1
  822. X
  823. Xstatic void corrupted(fullname, zf)
  824. X     char  *fullname;
  825. X     ZFILE *zf;
  826. X{
  827. X  zclose(zf);
  828. X  printf("%s: X Pixmap file is corrupted\n", fullname);
  829. X  exit(1);
  830. X}
  831. X
  832. XImage *xpixmapLoad(fullname, name, verbose)
  833. X     char         *fullname, *name;
  834. X     unsigned int  verbose;
  835. X{ ZFILE         *zf;
  836. X  char           buf[BUFSIZ];
  837. X  char           what[BUFSIZ];
  838. X  char          *p;
  839. X  unsigned int   value;
  840. X  unsigned int   format;  /* image format */
  841. X  unsigned int   w, h;    /* image dimensions */
  842. X  unsigned int   cpp;     /* chars per pixel */
  843. X  unsigned int   ncolors; /* number of colors */
  844. X  unsigned int   depth;   /* depth of image */
  845. X  char         **ctable;  /* color table */
  846. X  Image         *image;
  847. X  XColor         xcolor;
  848. X  unsigned int   a, b, x, y;
  849. X  int            c;
  850. X  byte          *dptr;
  851. X
  852. X  if (! (zf= zopen(fullname)))
  853. X    return(NULL);
  854. X
  855. X  /* read #defines until we have all that are necessary or until we
  856. X   * get an error
  857. X   */
  858. X
  859. X  format= w= h= ncolors= 0;
  860. X  for (;;) {
  861. X    if (! zgets(buf, BUFSIZ - 1, zf)) {
  862. X      zclose(zf);
  863. X      return(NULL);
  864. X    }
  865. X    if (!strncmp(buf, "#define", 7)) {
  866. X      if (sscanf(buf, "#define %s %d", what, &value) != 2) {
  867. X    zclose(zf);
  868. X    return(NULL);
  869. X      }
  870. X      if (! (p= rindex(what, '_')))
  871. X    p= what;
  872. X      else
  873. X    p++;
  874. X      if (!strcmp(p, "format"))
  875. X    format= value;
  876. X      else if (!strcmp(p, "width"))
  877. X    w= value;
  878. X      else if (!strcmp(p, "height"))
  879. X    h= value;
  880. X      else if (!strcmp(p, "ncolors"))
  881. X    ncolors= value;
  882. X
  883. X      /* this one is ugly
  884. X       */
  885. X
  886. X      else if (!strcmp(p, "pixel")) { /* this isn't pretty but it works */
  887. X    if (p == what)
  888. X      continue;
  889. X    *(--p)= '\0';
  890. X    if (!(p= rindex(what, '_')) || (p == what) || strcmp(++p, "per"))
  891. X      continue;
  892. X    *(--p)= '\0';
  893. X    if (!(p= rindex(what, '_')))
  894. X      p= what;
  895. X    if (strcmp(++p, "chars"))
  896. X      continue;
  897. X    cpp= value;
  898. X      }
  899. X    }
  900. X    else if ((sscanf(buf, "static char * %s", what) == 1) &&
  901. X         (p= rindex(what, '_')) && !strcmp(++p, "colors[]"))
  902. X      break;
  903. X  }
  904. X
  905. X  if ((format != XPM_FORMAT) || !w || !h || !ncolors || !cpp) {
  906. X    zclose(zf);
  907. X    return(NULL);
  908. X  }
  909. X
  910. X  if (p= rindex(what, '_')) {     /* get the name in the image if there is */
  911. X    *p= '\0';                     /* one */
  912. X    image->title= dupString(what);
  913. X  }
  914. X  else {
  915. X    p= what;
  916. X    image->title= dupString(name);
  917. X  }
  918. X
  919. X  if (verbose)
  920. X    printf("%s is a %dx%d X Pixmap image with %d colors titled '%s'\n",
  921. X       name, w, h, ncolors, image->title);
  922. X
  923. X  for (depth= 1, value= 2; value < ncolors; value <<= 1, depth++)
  924. X    ;
  925. X  image= newRGBImage(w, h, depth);
  926. X  image->rgb.used= ncolors;
  927. X
  928. X  /* read the colors array and build the image colormap
  929. X   */
  930. X
  931. X  ctable= (char **)lmalloc(sizeof(char *) * ncolors);
  932. X  xcolor.flags= DoRed | DoGreen | DoBlue;
  933. X  for (a= 0; a < ncolors; a++) {
  934. X    /* read pixel value
  935. X     */
  936. X
  937. X    *(ctable + a)= (char *)lmalloc(cpp);
  938. X    while (((c= zgetc(zf)) != EOF) && (c != '"'))
  939. X      ;
  940. X    if (c == EOF)
  941. X      corrupted(fullname, zf);
  942. X    for (b= 0; b < cpp; b++) {
  943. X      if ((c= zgetc(zf)) == '\\')
  944. X    c= zgetc(zf);
  945. X     if (c == EOF)
  946. X    corrupted(fullname, zf);
  947. X      *(*(ctable + a) + b)= (char)c;
  948. X    }
  949. X    if (((c= zgetc(zf)) == EOF) || (c != '"'))
  950. X      corrupted(fullname, zf);
  951. X
  952. X    /* read color definition and parse it
  953. X     */
  954. X
  955. X    while (((c= zgetc(zf)) != EOF) && (c != '"'))
  956. X      ;
  957. X    if (c == EOF)
  958. X      corrupted(fullname, zf);
  959. X    for (b= 0; ((c= zgetc(zf)) != EOF) && (c != '"'); b++) {
  960. X      if (c == '\\')
  961. X    c= zgetc(zf);
  962. X      if (c == EOF)
  963. X    corrupted(fullname, zf);
  964. X      buf[b]= (char)c;
  965. X    }
  966. X    buf[b]= '\0';
  967. X
  968. X    if (Disp) {
  969. X      if (! XParseColor(Disp, DefaultColormap(Disp, Scrn), buf, &xcolor)) {
  970. X    printf("%s: %s: Bad color name\n", fullname, buf);
  971. X    exit(1);
  972. X      }
  973. X      *(image->rgb.red + a)= xcolor.red;
  974. X      *(image->rgb.green + a)= xcolor.green;
  975. X      *(image->rgb.blue + a)= xcolor.blue;
  976. X    }
  977. X  }
  978. X
  979. X  for (;;) {
  980. X    if (! zgets(buf, BUFSIZ - 1, zf))
  981. X      corrupted(fullname, zf);
  982. X    if (sscanf(buf, "static char * %s", what) == 1)
  983. X      break;
  984. X  }
  985. X
  986. X  if (p= rindex(what, '_'))
  987. X    p++;
  988. X  else
  989. X    p= what;
  990. X  if (strcmp(p, "pixels[]"))
  991. X    corrupted(fullname, zf);
  992. X
  993. X  /* read in image data
  994. X   */
  995. X
  996. X  dptr= image->data;
  997. X  for (y= 0; y < h; y++) {
  998. X    while (((c= zgetc(zf)) != EOF) && (c != '"'))
  999. X      ;
  1000. X    for (x= 0; x < w; x++) {
  1001. X      for (a= 0; a < cpp; a++) {
  1002. X    if ((c= zgetc(zf)) == '\\')
  1003. X      c= zgetc(zf);
  1004. X    if (c == EOF)
  1005. X      corrupted(fullname, zf);
  1006. X    buf[a]= (char)c;
  1007. X      }
  1008. X      for (a= 0; a < ncolors; a++)
  1009. X    if (!strncmp(*(ctable + a), buf, cpp))
  1010. X      break;
  1011. X      if (a == ncolors) { /* major uncool */
  1012. X    zclose(zf);
  1013. X    printf("%s: Pixel data doesn't match color data\n", fullname);
  1014. X    exit(1);
  1015. X      }
  1016. X      valToMem((unsigned long)a, dptr, image->pixlen);
  1017. X      dptr += image->pixlen;
  1018. X    }
  1019. X    if ((c= zgetc(zf)) != '"')
  1020. X      corrupted(fullname, zf);
  1021. X  }
  1022. X  return(image);
  1023. X}
  1024. X
  1025. Xint xpixmapIdent(fullname, name)
  1026. X{ Image *image;
  1027. X
  1028. X  if (image= xpixmapLoad(fullname, name, 1)) {
  1029. X    freeImage(image);
  1030. X    return(1);
  1031. X  }
  1032. X  return(0);
  1033. X}
  1034. END_OF_xpixmap.c
  1035. if test 5707 -ne `wc -c <xpixmap.c`; then
  1036.     echo shar: \"xpixmap.c\" unpacked with wrong size!
  1037. fi
  1038. # end of overwriting check
  1039. fi
  1040. echo shar: End of shell archive.
  1041. exit 0
  1042.